package org.leyi.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.leyi.shop.common.annotation.IsLogin;
import org.leyi.shop.common.annotation.IsSuperAdmin;
import org.leyi.shop.common.exception.BusinessException;
import org.leyi.shop.common.response.EnumResponse;
import org.leyi.shop.mapper.UserMapper;
import org.leyi.shop.model.pojo.User;
import org.leyi.shop.model.vo.SafetyUser;
import org.leyi.shop.service.UserService;
import org.leyi.shop.util.HttpServletUtils;
import org.leyi.shop.util.IDRandomUtils;
import org.leyi.shop.util.Verifier;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.stream.Collectors;

import static org.leyi.shop.common.Constant.*;

/**
* @author lenovo
* description: 针对表【user(用户表)】的数据库操作Service实现 还存在有bug，当修改了权限后登录态无法及时更新的情况
* create 2024-05-04 23:18:42
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Resource
    private UserMapper userMapper;
    @Override
    public Long register(String userAccount, String userPassword) {
        //校验数据
        if(StringUtils.isAllBlank(userAccount,userPassword))
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        //账号和密码至少6位,且不包含字符
        if(!Verifier.onlyContainsNumAndAlpha(userAccount)||userAccount.length()<6)
        {
            throw new BusinessException(EnumResponse.USER_ACCOUNT_INVALID_ERR);
        }
        //密码过短
        if(userPassword.length()<6)
        {
            throw  new BusinessException(EnumResponse.PASSWORD_SHORT_ERR);
        }
        //判断该账号是否在数据库里存在
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_account",userAccount);
        long count = this.count(wrapper);
        if(count>0)
        {
            throw new BusinessException(EnumResponse.USER_ACCOUNT_REPEAT_ERR);
        }
        //密码加密
        String encryptPassword = DigestUtils.md5DigestAsHex((userPassword + PASSWORD_SALT).getBytes());
        User user = new User();
        user.setId(IDRandomUtils.getDefaultId());
        user.setUserName("暂时没有名字");
        user.setUserAccount(userAccount);
        user.setUserPassword(encryptPassword);
        user.setBirthday(null);
        user.setContact(null);
        user.setProductPoints(0.0D);
        user.setAddress(new Gson().toJson(new Object()));
        user.setRole(0);
        user.setLastIp(null);
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setDeleteLogic(0);
        user.setGender(0);
        user.setAvatarUrl(null);
        if(!this.save(user))
        {
            throw new BusinessException(EnumResponse.SERVICE_REQUEST_ERR,"注册失败");
        }
        return user.getId();
    }

    @Override
    public SafetyUser login(String userAccount, String userPassword, HttpServletRequest request) {
        //校验数据
        if(request==null)
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        if(StringUtils.isAllBlank(userAccount,userPassword))
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        //账号至少6位,且不包含字符
        if(!Verifier.onlyContainsNumAndAlpha(userAccount)||userAccount.length()<6)
        {
            throw new BusinessException(EnumResponse.USER_ACCOUNT_INVALID_ERR);
        }
        //密码加密
        String encryptPassword = DigestUtils.md5DigestAsHex((userPassword + PASSWORD_SALT).getBytes());
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        User user = userMapper.selectOne(wrapper.eq("user_account", userAccount).eq("user_password", encryptPassword));
        if(user==null)
        {
            throw  new BusinessException(EnumResponse.SERVICE_REQUEST_ERR,"登录失败，请重试");
        }
        if(!encryptPassword.equals(user.getUserPassword()))
        {
            throw new BusinessException(EnumResponse.PASSWORD_ERR);
        }
        //获取ip
        user.setLastIp(request.getRemoteUser());
        this.updateById(user);
        SafetyUser safetyUser = new SafetyUser();
        //将登录态放进session
        BeanUtils.copyProperties(user,safetyUser);
        request.getSession().setAttribute(REQUEST_SESSION_USER_KEY,safetyUser);

        return safetyUser;
    }

    @Override
    public SafetyUser registerByWechat(String userAccount) {
        return null;
    }

    @IsLogin
    @Override
    public void deleteUserById(Long id) {
        if(id==null||id<0)
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        SafetyUser currentUser = HttpServletUtils.getCurrentUser();
        //仅允许用户本人或者管理员注销账号
        if(!Objects.equals(currentUser.getId(), id) ||currentUser.getRole()<ADMIN_ROLE)
        {
            throw new BusinessException(EnumResponse.AUTHORITY_ERR);
        }
        if(!this.removeById(id))
        {
            throw new BusinessException(EnumResponse.SERVICE_REQUEST_ERR,"删除失败了");
        }

    }

    @IsLogin
    @Override
    public SafetyUser modifyUser(SafetyUser safetyUser) {
        if(safetyUser==null||safetyUser.getId()==null||safetyUser.getId()<0)
        {
            throw  new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        SafetyUser currentUser = HttpServletUtils.getCurrentUser();
        //仅允许用户本人或者管理员更改个人信息
        if(!Objects.equals(currentUser.getId(), safetyUser.getId()) ||currentUser.getRole()<ADMIN_ROLE)
        {
            throw new BusinessException(EnumResponse.AUTHORITY_ERR);
        }
        User user = new User();
        BeanUtils.copyProperties(safetyUser,user);
        if(!this.updateById(user))
        {
            throw  new BusinessException(EnumResponse.SERVICE_REQUEST_ERR,"修改信息失败了，请重试");
        }
        //如果是个人修改将登录态放进session
        if(Objects.equals(currentUser.getId(), safetyUser.getId()) )
        {  HttpServletUtils.getHttpServletRequest().getSession().setAttribute(REQUEST_SESSION_USER_KEY,safetyUser);}
        return safetyUser;
    }

    @Override
    public List<SafetyUser> searchUserById(Long id) {
        if(id==null||id<0)
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }

        List<User> userList = userMapper.selectList(new QueryWrapper<User>().like("id", id));
        return userList==null?new ArrayList<>(): userList.stream().map((user) -> {
                    SafetyUser safetyUser = new SafetyUser();
                    BeanUtils.copyProperties(user,safetyUser);return safetyUser;})
                .collect(Collectors.toList());
    }
    @IsLogin
    @Override
    public void modifyUserPassword(Long id, String oldPassword, String newPassword) {

        if(id==null||id<0||StringUtils.isAllBlank(oldPassword,newPassword))
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        SafetyUser currentUser = HttpServletUtils.getCurrentUser();
        //非本人不能修改
        if(!Objects.equals(currentUser.getId(), id))
        {
            throw new BusinessException(EnumResponse.AUTHORITY_ERR);
        }
        if(oldPassword.length()<6||newPassword.length()<6)
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        //密码相等就不修改
        if(newPassword.equals(oldPassword))
        {
            return;
        }
        String encryptOldPassword = DigestUtils.md5DigestAsHex((oldPassword + PASSWORD_SALT).getBytes());
        String encryptNewPassword = DigestUtils.md5DigestAsHex((newPassword + PASSWORD_SALT).getBytes());
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", id).eq("user_password", oldPassword));
        if(user==null)
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        if(!encryptOldPassword.equals(user.getUserPassword()))
        {
            throw new BusinessException(EnumResponse.PASSWORD_ERR);
        }
        user.setUserPassword(encryptNewPassword);
        if(!this.updateById(user)) {
            throw new BusinessException(EnumResponse.SERVICE_REQUEST_ERR, "修改信息失败了，请重试");
        }
    }
    @IsSuperAdmin
    @Override
    public void modifyUserRole(Long id, Integer updateRole) {
        if(id==null||id<0||updateRole==null||updateRole<0||updateRole>SUPER_ADMIN_ROLE)
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        userMapper.update(new UpdateWrapper<User>().eq("id",id).setSql("role="+updateRole));
    }
    @Override
    public List<SafetyUser> searchUserByName(String userName) {
        if(StringUtils.isBlank(userName))
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        List<User> userList = userMapper.selectList(new QueryWrapper<User>().like("user_name", userName));

        return userList==null?new ArrayList<>(): userList.stream().map((user) -> {
                    SafetyUser safetyUser = new SafetyUser();
                    BeanUtils.copyProperties(user,safetyUser);return safetyUser;})
                .collect(Collectors.toList());
    }
    @Override
    public List<SafetyUser> searchUserByAccount(String userAccount) {
        if(StringUtils.isBlank(userAccount))
        {
            throw new BusinessException(EnumResponse.PARAMETER_ERR);
        }
        List<User> userList = userMapper.selectList(new QueryWrapper<User>().like("user_account", userAccount));

        return userList==null?new ArrayList<>(): userList.stream().map((user) -> {
                    SafetyUser safetyUser = new SafetyUser();
                    BeanUtils.copyProperties(user,safetyUser);return safetyUser;})
                .collect(Collectors.toList());
    }
    @IsLogin
    @Override
    public SafetyUser getCurrentUser() {
        HttpServletRequest request=HttpServletUtils.getHttpServletRequest();
        SafetyUser currentUser = HttpServletUtils.getCurrentUser();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", currentUser.getId()));
        if(user==null)
        {
            throw new BusinessException(EnumResponse.USER_NOT_LOGIN);
        }
        //将登录态放进session
        BeanUtils.copyProperties(user,currentUser);
        request.getSession().setAttribute(REQUEST_SESSION_USER_KEY,currentUser);
        return currentUser;
    }
    @IsLogin
    @Override
    public void logout(HttpServletRequest request)
    {
        request.getSession().removeAttribute(REQUEST_SESSION_USER_KEY);
    }
}




